package com.loong.android;

import android.app.NotificationChannel;
import android.app.PendingIntent;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;

import androidx.core.app.NotificationCompat;

/**
 * 通知构造器
 */
public class NotificationBuilder {
    private final Context context;
    private final NotificationCompat.Builder builder;
    private NotificationChannel channel;

    public NotificationBuilder(Context context, String channelId, String channelName, int importance) {
        this.context = context;
        builder = new NotificationCompat.Builder(context, channelId);
        if(Build.VERSION.SDK_INT >= 26) {
            channel = new NotificationChannel(channelId, channelName, importance);
        }
    }

    /**
     * 返回操作的androidx.core.app.NotificationCompat.Builder对象
     */
    public NotificationCompat.Builder getRaw() {
        return builder;
    }

    /**
     * 返回操作的android.app.NotificationChannel对象
     */
    public NotificationChannel getRawChannel() {
        return channel;
    }

    /**
     * 设置是否允许绕过请勿打扰，在安卓8(api26)及以上版本的系统才有效
     *
     * @param enable 是否启用
     */
    public NotificationBuilder setBypassDnd(boolean enable) {
        if(Build.VERSION.SDK_INT >= 26 && channel != null) {
            channel.setBypassDnd(enable);
        }
        return this;
    }

    /**
     * 设置是否允许显示气泡，在安卓10(api29)及以上版本的系统才有效
     *
     * @param enable 是否启用
     */
    public NotificationBuilder setAllowBubbles(boolean enable) {
        if(Build.VERSION.SDK_INT >= 29 && channel != null) {
            channel.setAllowBubbles(enable);
        }
        return this;
    }

    /**
     * 设置是否开启呼吸灯，在安卓8(api26)及以上版本的系统才有效
     *
     * @param enable 是否启用
     */
    public NotificationBuilder enableLights(boolean enable) {
        if(Build.VERSION.SDK_INT >= 26 && channel != null) {
            channel.enableLights(enable);
        }
        return this;
    }

    /**
     * 设置是否开启振动器，在安卓8(api26)及以上版本的系统才有效。另外，需要手动添加权限声明：android.permission.VIBRATE
     *
     * @param enable 是否启用
     */
    public NotificationBuilder enableVibration(boolean enable) {
        if(Build.VERSION.SDK_INT >= 26 && channel != null) {
            channel.enableVibration(enable);
        }
        return this;
    }

    /**
     * 设置是否在桌面图标上显示消息数量角标，在安卓8(api26)及以上版本的系统才有效。
     *
     * @param vibrationPattern 振动器持续时间数组。
     */
    public NotificationBuilder setVibrationPattern(long[] vibrationPattern) {
        if(Build.VERSION.SDK_INT >= 26 && channel != null) {
            channel.setVibrationPattern(vibrationPattern);
        }
        return this;
    }

    /**
     * 设置通知在锁屏状态的可见性，在安卓8(api26)及以上版本的系统才有效。另外，需要手动添加权限声明：android.permission.VIBRATE
     *
     * @param visibility 可见性标志值。参考通知类的可见性表
     */
    public NotificationBuilder setLockscreenVisibility(int visibility) {
        if(Build.VERSION.SDK_INT >= 26 && channel != null) {
            channel.setLockscreenVisibility(visibility);
        }
        return this;
    }

    /**
     * 设置呼吸灯颜色值，在安卓8(api26)及以上版本的系统才有效。
     *
     * @param color 颜色值
     */
    public NotificationBuilder setLightColor(int color) {
        if(Build.VERSION.SDK_INT >= 26 && channel != null) {
            channel.setLightColor(color);
        }
        return this;
    }

    /**
     * 设置是否在桌面图标上显示消息数量角标，在安卓8(api26)及以上版本的系统才有效。
     *
     * @param enable 是否启用
     */
    public NotificationBuilder setShowBadge(boolean enable) {
        if(Build.VERSION.SDK_INT >= 26 && channel != null) {
            channel.setShowBadge(enable);
        }
        return this;
    }

    /**
     * 设置标题
     *
     * @param title 标题内容
     */
    public NotificationBuilder setContentTitle(String title) {
        builder.setContentTitle(title);
        return this;
    }

    /**
     * 设置文本内容
     *
     * @param text 文本内容
     */
    public NotificationBuilder setContentText(String text) {
        builder.setContentText(text);
        return this;
    }

    /**
     * 设置内容信息
     *
     * @param info 信息内容
     */
    public NotificationBuilder setContentInfo(String info) {
        builder.setContentInfo(info);
        return this;
    }

    /**
     * 置设置内容
     *
     * @param text 文本内容
     */
    public NotificationBuilder setSettingsText(String text) {
        builder.setSettingsText(text);
        return this;
    }

    /**
     * 设置可否自动取消
     *
     * @param enable 是否启用
     */
    public NotificationBuilder setAutoCancel(boolean enable) {
        builder.setAutoCancel(enable);
        return this;
    }

    /**
     * 设置类别
     *
     * @param category 类别名称
     */
    public NotificationBuilder setCategory(String category) {
        builder.setCategory(category);
        return this;
    }

    /**
     * 设置颜色
     *
     * @param color 颜色值
     */
    public NotificationBuilder setColor(int color) {
        builder.setColor(color);
        return this;
    }

    /**
     * 设置额外的数据
     *
     * @param data 绑定数据对象
     */
    public NotificationBuilder setExtras(Bundle data) {
        builder.setExtras(data);
        return this;
    }

    /**
     * 设置大图
     *
     * @param bitmap 位图数据
     */
    public NotificationBuilder setLargeIcon(Bitmap bitmap) {
        builder.setLargeIcon(bitmap);
        return this;
    }

    /**
     * 设置桌面图标角标图片类型
     *
     * @param iconType 图标类型
     */
    public NotificationBuilder setBadgeIconType(int iconType) {
        builder.setBadgeIconType(iconType);
        return this;
    }

    /**
     * 设置小图
     *
     * @param resId 图片资源id
     */
    public NotificationBuilder setSmallIcon(int resId) {
        builder.setSmallIcon(resId);
        return this;
    }

    /**
     * 设置通道id
     *
     * @param channelId 通道id
     */
    public NotificationBuilder setChannelId(String channelId) {
        builder.setChannelId(channelId);
        return this;
    }

    /**
     * 设置是否启用彩色
     *
     * @param enable 是否启用
     */
    public NotificationBuilder Colorized(boolean enable) {
        builder.setColorized(enable);
        return this;
    }

    /**
     * 设置呼吸灯颜色和呼吸开关时间
     *
     * @param color 颜色值
     * @param onMs 开启时间，单位为毫秒
     * @param offMs 关闭时间，单位为毫秒
     */
    public NotificationBuilder setLights(int color, int onMs, int offMs) {
        builder.setLights(color, onMs, offMs);
        return this;
    }

    /**
     * 设置数量
     *
     * @param num 数量
     */
    public NotificationBuilder setNumber(int num) {
        builder.setNumber(num);
        return this;
    }

    /**
     * 设置在状态栏显示的通知内容
     *
     * @param text 文本内容
     */
    public NotificationBuilder setTicker(String text) {
        builder.setTicker(text);
        return this;
    }

    /**
     * 设置附带信息
     *
     * @param text 文本内容
     */
    public NotificationBuilder setSubText(String text) {
        builder.setSubText(text);
        return this;
    }

    /**
     * 设置是否启用指定时间显示通知的功能
     *
     * @param enable 持续时间，单位为毫秒
     */
    public NotificationBuilder setShowWhen(boolean enable) {
        builder.setShowWhen(enable);
        return this;
    }

    /**
     * 设置什么时候开始显示
     *
     * @param when 开始显示的时间戳
     */
    public NotificationBuilder setWhen(long when) {
        builder.setWhen(when);
        return this;
    }

    /**
     * 设置通知的可见性
     *
     * @param visibility 通知的可见性标志值，参考通知类的可见性表
     */
    public NotificationBuilder setVisibility(int visibility) {
        builder.setVisibility(visibility);
        return this;
    }

    /**
     * 设置通知振动的持续时间数组
     *
     * @param pattern 持续时间数组
     */
    public NotificationBuilder setVibrate(long[] pattern) {
        builder.setVibrate(pattern);
        return this;
    }

    /**
     * 设置通知显示的持续时间
     *
     * @param duration 持续时间，单位为毫秒
     */
    public NotificationBuilder setDuration(long duration) {
        builder.setTimeoutAfter(duration);
        return this;
    }

    /**
     * 设置是否为静默通知
     *
     * @param enable 如果为 true，则不管通知或通知通道上设置的声音或振动如何，都会使该通知实例静音。
     *               如果为 false，则应用正常的声音和振动逻辑。 默认为假。
     */
    public NotificationBuilder setSilent(boolean enable) {
        builder.setSilent(enable);
        return this;
    }

    /**
     * 设置优先级
     *
     * @param priority 参考通知类的优先级表
     */
    public NotificationBuilder setPriority(int priority) {
        builder.setPriority(priority);
        return this;
    }

    /**
     * 设置此通知是否仅与当前设备相关。
     * 一些通知可以桥接到其他设备进行远程显示。 可以设置此提示以建议不要桥接此通知。
     *
     * @param enable 是否启用
     */
    public NotificationBuilder setLocalOnly(boolean enable) {
        builder.setLocalOnly(enable);
        return this;
    }

    /**
     * 设置是否仅显示一次
     *
     * @param enable 是否启用
     */
    public NotificationBuilder setOnlyAlertOnce(boolean enable) {
        builder.setOnlyAlertOnce(enable);
        return this;
    }

    /**
     * 设置这是否是持续通知。
     * 用户不能关闭正在进行的通知，因此您的应用程序或服务必须注意取消它们。
     * 它们通常用于指示用户正在积极参与的后台任务（例如，播放音乐）或以某种方式挂起并因此占用设备（例如，文件下载、同步操作、活动网络连接）。
     *
     * @param enable 是否启用
     */
    public NotificationBuilder setOngoing(boolean enable) {
        builder.setOngoing(enable);
        return this;
    }

    /**
     * 取额外数据
     */
    public Bundle getExtras() {
        return builder.getExtras();
    }

    /**
     * 设置进度
     *
     * @param max 最大进度
     * @param progress 当前进度
     * @param indeterminate 为不确定的进度
     */
    public NotificationBuilder setProgress(int max, int progress, boolean indeterminate) {
        builder.setProgress(max, progress, indeterminate);
        return this;
    }

    /**
     * 设置样式
     *
     * @param styleObject 样式对象
     */
    public NotificationBuilder setStyle(NotificationCompat.Style styleObject) {
        builder.setStyle(styleObject);
        return this;
    }

    /**
     * 设置内容意图
     *
     * @param pendingIntent 代办意图数据对象
     */
    public NotificationBuilder setContentIntent(PendingIntent pendingIntent) {
        builder.setContentIntent(pendingIntent);
        return this;
    }

    /**
     * 设置删除意图
     *
     * @param pendingIntent 代办意图数据对象
     */
    public NotificationBuilder setDeleteIntent(PendingIntent pendingIntent) {
        builder.setDeleteIntent(pendingIntent);
        return this;
    }

    /**
     * 设置全屏意图
     *
     * @param pendingIntent 代办意图数据对象
     * @param highPriority 是否拥有高优先级
     */
    public NotificationBuilder setFullScreenIntent(PendingIntent pendingIntent, boolean highPriority) {
        builder.setFullScreenIntent(pendingIntent, highPriority);
        return this;
    }

    /**
     * 生成通知类
     */
    public LonNotification build() {
        android.app.NotificationManager manager = (android.app.NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        if(Build.VERSION.SDK_INT >= 26 && channel != null) {
            manager.createNotificationChannel(channel);
        }
        return new LonNotification(builder.build());
    }

}
